﻿
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Linq.Expressions;
using Common.Framework.EntityMaster;

namespace Common.Framework.CommonDAL
{
    /// <summary>
    ///     EntityFramework 数据库底层操作接口
    /// </summary>
    public interface IContextAdapter
    {
        /// <summary>
        ///     获得一个实体的主键名称
        /// </summary>
        /// <param name="entityType">实体类的类型信息对象</param>
        /// <returns>主键名称</returns>
        string GetKeyName(Type entityType);

        /// <summary>
        ///     添加对象
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="entity">entity</param>
        /// <param name="callDelegate">委托函数，级联删除是可以使用</param>
        /// <returns>int</returns>
        int AddObject<TEntity>(TEntity entity, Action<SetEntityState> callDelegate = null) where TEntity : class;


        /// <summary>
        ///     批量添加对象
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="entityList"><![CDATA[IEnumerable<TEntity>]]></param>
        /// <param name="callDelegate">委托函数，级联删除是可以使用</param>
        /// <returns>int</returns>
        int AddObject<TEntity>(IEnumerable<TEntity> entityList, Action<SetEntityState> callDelegate = null)
            where TEntity : class;


        /// <summary>
        ///     修改对象
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="entity">entity</param>
        /// <param name="callDelegate">委托函数，级联删除是可以使用</param>
        /// <returns>int</returns>
        int UpdateObject<TEntity>(TEntity entity, Action<SetEntityState> callDelegate = null) where TEntity : class;


        /// <summary>
        ///     批量修改
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="entityList"><![CDATA[IEnumerable<TEntity>]]></param>
        /// <param name="callDelegate">委托函数，级联删除是可以使用</param>
        /// <returns>int</returns>
        int UpdateObject<TEntity>(IEnumerable<TEntity> entityList, Action<SetEntityState> callDelegate = null)
            where TEntity : class;


        /// <summary>
        ///     更新实体对象
        /// </summary>
        /// <typeparam name="TEntity">Class</typeparam>
        /// <param name="filterExpression">过滤条件</param>
        /// <param name="updateExpression">更新实体对象</param>
        /// <returns>更新记录条数</returns>
        int UpdateObject<TEntity>(Expression<Func<TEntity, bool>> filterExpression,
            Expression<Func<TEntity, TEntity>> updateExpression)
            where TEntity : class;


        /// <summary>
        ///     批量更新实体对象
        /// </summary>
        /// <typeparam name="TEntity">Class</typeparam>
        /// <param name="updateExpressions">更新表达式集合</param>
        /// <returns>更新记录条数</returns>
        int UpdateObject<TEntity>(IEnumerable<UpdateExpressionsEntity<TEntity>> updateExpressions)
            where TEntity : class, new();


        /// <summary>
        ///     删除对象
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="entity">entity</param>
        /// <param name="callDelegate">委托函数，级联删除是可以使用</param>
        /// <returns>int</returns>
        int DeleteObject<TEntity>(TEntity entity, Action<SetEntityState> callDelegate = null) where TEntity : class;


        /// <summary>
        ///     批量删除
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="entityList"><![CDATA[IEnumerable<TEntity>]]></param>
        /// <param name="callDelegate">委托函数，级联删除是可以使用</param>
        /// <returns>int</returns>
        int DeleteObject<TEntity>(IEnumerable<TEntity> entityList, Action<SetEntityState> callDelegate = null)
            where TEntity : class;


        /// <summary>
        ///     根据条件删除
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="expression">lamda 表达式</param>
        /// <returns></returns>
        int DeleteObject<TEntity>(Expression<Func<TEntity, bool>> expression) where TEntity : class;


        /// <summary>
        ///     根据条件删除
        /// </summary>
        /// <typeparam name="TEntity">class </typeparam>
        /// <param name="filterExpression">过滤表达式</param>
        /// <returns></returns>
        int DeleteObject2<TEntity>(Expression<Func<TEntity, bool>> filterExpression) where TEntity : class;


        /// <summary>
        ///     根据主键值获取对象
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="primaryKeyValue">主键值</param>
        /// <returns>TEntity</returns>
        TEntity GetEntity<TEntity>(object primaryKeyValue) where TEntity : class;


        /// <summary>
        ///     查询单个对象
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="expression">lamda 表达式</param>
        /// <param name="includePath">关联路径</param>
        /// <returns>TEntity</returns>
        TEntity GetEntity<TEntity>(Expression<Func<TEntity, bool>> expression, params string[] includePath)
            where TEntity : class;


        /// <summary>
        ///     查询对象集合
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="expression">lamda 表达式</param>
        /// <param name="includePath">关联路径</param>
        /// <returns><![CDATA[IEnumerable<TEntity>]]></returns>
        IEnumerable<TEntity> GetList<TEntity>(Expression<Func<TEntity, bool>> expression, params string[] includePath)
            where TEntity : class;



        /// <summary>
        ///     查询分页对象集合
        /// </summary>
        /// <typeparam name="TEntity">class TEntity</typeparam>
        /// <param name="expression">条件表达式</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="pageSize">每页显示数量</param>
        /// <param name="totalCount">ref 返回总记录条数</param>
        /// <param name="orderByProperty">排序字段</param>
        /// <param name="isDesc">是否降序</param>
        /// <param name="includePath">关联路径</param>
        /// <returns></returns>
        IEnumerable<TEntity> GetPager<TEntity>(Expression<Func<TEntity, bool>> expression,
            int pageIndex,
            int pageSize,
            ref long totalCount,
            string orderByProperty,
            bool isDesc,
            params string[] includePath) where TEntity : class;



        /// <summary>
        ///     对数据库执行给定的 DDL/DML 命令。
        /// </summary>
        /// <param name="sql">命令字符串。</param>
        /// <param name="parmaeters">要应用于命令字符串的参数。SqlParameter</param>
        /// <returns>int</returns>
        int ExecuteSqlCommand(string sql, params object[] parmaeters);


        /// <summary>
        ///     创建一个原始 SQL 查询，该查询将返回给定泛型类型的元素。类型可以是包含与从查询返回的列名匹配的属性的任何类型，也可以是简单的基元类型
        /// </summary>
        /// <typeparam name="TEntity">查询所返回对象的类型。</typeparam>
        /// <param name="sql"> SQL 查询字符串。</param>
        /// <param name="parmaeters">要应用于 SQL 查询字符串的参数。SqlParameter</param>
        /// <returns><![CDATA[IEnumerable<TEntity>]]></returns>
        IEnumerable<TEntity> SqlQuery<TEntity>(string sql, params object[] parmaeters);


        /// <summary>
        ///     执行存储过程
        /// </summary>
        /// <param name="procedureName">存储过程名称</param>
        /// <param name="parmaeters">要应用于存储过程的字符串的参数。 SqlParameter</param>
        /// <returns>dynamic</returns>
        DataSet ExecuteProcedure(string procedureName, params object[] parmaeters);
    }
}